package com.pcl.ocr.scanner

import android.graphics.*
import android.os.Handler
import android.os.Message
import android.util.Log
import com.pcl.ocr.scanner.ScannerView
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import org.opencv.core.Mat
import com.pcl.ocr.utils.PlateRecognition
import com.pcl.ocr.scanner.CameraAnalyzer
import com.pcl.ocr.utils.toBitmap
import org.opencv.android.Utils
import org.opencv.core.CvType
import java.io.ByteArrayOutputStream
import java.io.IOException

/**
 * @auther : Aleyn
 * time   : 2020/05/27
 */
class CameraAnalyzer internal constructor(private val scannerView: ScannerView) :
    ImageAnalysis.Analyzer {
    private var prAddress: Long = 0
    private var previewHandler: Handler? = null
    fun setHandle(previewHandler: Handler?) {
        this.previewHandler = previewHandler
    }

    override fun analyze(image: ImageProxy) {
        if (previewHandler != null) {
            val mat = ImagetoMat(image)
            if (mat != null) {
                if (prAddress == 0L) {
                    prAddress = scannerView.prAddress
                    image.close()
                    return
                }
                val res = PlateRecognition.SimpleRecognization(mat.nativeObjAddr, prAddress)
                val message: Message
                if ("" != res) {
                    message = Message.obtain(previewHandler, Scanner.OCR_SUCCEEDED, res)
                    previewHandler = null
                } else {
                    message = Message.obtain(previewHandler, Scanner.OCR_FAILED)
                }
                message.sendToTarget()
            }
        }
        try {
            Thread.sleep(100)
        } catch (e: InterruptedException) {
            e.printStackTrace()
            image.close()
        }
        image.close()
    }

    private fun ImagetoMat(imageProxy: ImageProxy): Mat? {
//        val plane = imageProxy.planes
//        val yBuffer = plane[0].buffer // Y
//        val uBuffer = plane[1].buffer // U
//        val vBuffer = plane[2].buffer // V
//        val ySize = yBuffer.remaining()
//        val uSize = uBuffer.remaining()
//        val vSize = vBuffer.remaining()
//        val nv21 = ByteArray(ySize + uSize + vSize)
//
//        //U and V are swapped
//        yBuffer[nv21, 0, ySize]
//        vBuffer[nv21, ySize, vSize]
//        uBuffer[nv21, ySize + vSize, uSize]
        try {
//            val yuvImage =
//                YuvImage(nv21, ImageFormat.NV21, imageProxy.width, imageProxy.height, null)
//            val stream = ByteArrayOutputStream(nv21.size)
//            yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 90, stream)
            var bitmap = imageProxy.toBitmap()
//            var bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size())
            val matrix = Matrix()
            matrix.postRotate(90f)
            val rect = scannerView.getFramingRectInPreview(bitmap!!.width, bitmap!!.height)
            bitmap = Bitmap.createBitmap(
                bitmap!!,
                rect.top,
                rect.left,
                rect.height(),
                rect.width(),
                matrix,
                true
            )
//            stream.close()
            val mat = Mat(bitmap.width, bitmap.height, CvType.CV_8UC4)
            Utils.bitmapToMat(bitmap, mat)
            return mat
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return null
    }

    companion object {
        private val TAG = CameraAnalyzer::class.java.simpleName
    }
}